"""Module used to find config file and load it
look for ini file in:

os.getcwd()
this_module_path = os.path.abspath(os.path.dirname(__file__))
My documents
home dir (docs and settings?)

"""

import imp, os, sys

try:
    #raise ImportError
    # from https://sourceforge.net/projects/pywin32/
    from win32com.shell import shell, shellcon
    have_win32extensions = True
except ImportError:
    have_win32extensions = False


## from http://www.voidspace.org.uk/python/configobj.html
## confi/ini file that preserves comments
# but not if you merge to a default dict... report bug?
#from configobj import ConfigObj


default_ini_filename = 'pytombo.ini'
default_dirname = None



## from http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe
## slightly modified
def main_is_frozen():
    return (hasattr(sys, "frozen") or # new py2exe
            hasattr(sys, "importers") # old py2exe
            or imp.is_frozen("__main__")) # tools/freeze

def get_main_dir():
    if main_is_frozen():
        return os.path.dirname(sys.executable)
    this_module_path = os.path.abspath(os.path.dirname(__file__))
    #return os.path.dirname(sys.argv[0])
    return this_module_path

##TODO check under py2exe if this works
#this_module_path = os.path.abspath(os.path.dirname(__file__))
this_module_path = get_main_dir()


def getHomeDir():
    ''' Try to find user's home directory, otherwise fail'''
    path=""
    try:
        path=os.path.expanduser("~")
        if path == "~":
            if sys.platform == 'Pocket PC':
                path = "\\My Documents"
            elif sys.platform.startswith("win"):
                #win98 hack ONLY, not needed if running in IDLE under win98 or Win2k and later
                import _winreg
                k = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
                (path, dummy) = _winreg.QueryValueEx(k, "Personal")
                # at this point clach04_home is _probably_ a Unicode string
            else:
                path=""
    except:
        try:
            path=os.environ["HOME"]
        except:
            path=os.environ["USERPROFILE"]

    return path


directory_search_order = [os.getcwd(), get_main_dir()]
if have_win32extensions:
    my_documents = shell.SHGetPathFromIDList (shell.SHGetSpecialFolderLocation (0, shellcon.CSIDL_PERSONAL))
    directory_search_order.append(my_documents)
    default_dirname = my_documents
directory_search_order.append(getHomeDir())
if default_dirname is None:
    default_dirname = getHomeDir()

#print 'directory_search_order', directory_search_order

def find_ini_path(ini_filename=None, dirs_to_search=None):
    """Attempts to find (and return) existing ini file name.
    returns None on failure to find
    
        - dirs_to_search list of difertories tp search, if not specified defaults
    """
    if ini_filename is None:
        ini_filename = default_ini_filename
    if dirs_to_search is None:
        dirs_to_search = directory_search_order
    
    full_ini_pathname = None
    for tmp_dirname in dirs_to_search:
        tmp_ini_filename = os.path.join(tmp_dirname, ini_filename)
        if os.path.exists(tmp_ini_filename):
            full_ini_pathname = tmp_ini_filename 
            break
    
    return full_ini_pathname
    
def get_ini_path(ini_filename=None, dirs_to_search=None, dir_if_not_found=None):
    """Attempts to find (and return) existing ini file name.
    If ini file can not be found default name is returned.
    
        - dirs_to_search list of difertories tp search, if not specified defaults
        - dir_if_not_found is the directory to find if no ini file is found
    """
    if ini_filename is None:
        ini_filename = default_ini_filename
    if dir_if_not_found is None:
        dir_if_not_found = default_dirname
    
    full_ini_pathname = find_ini_path(ini_filename, dirs_to_search)
    
    if full_ini_pathname is None:
        #print 'no ini file found, defaulting'
        full_ini_pathname = os.path.join(dir_if_not_found, ini_filename)
        
    #print 'full_ini_pathname =', full_ini_pathname
    full_ini_pathname = os.path.normpath(full_ini_pathname)
    return full_ini_pathname


def get_config(ini_filename=None):
    """Returns a config object that has a save method.
    Currently wraps ConfigObj(), may replace with another library."""
    try:
        from configobj import ConfigObj
    except ImportError:
        # temp hack
        # for maemo/limited api when we only wnt web tombo search (options are not critical
        def ConfigObj(x):
            if isinstance(x, dict):
                return x
            else:
                return {}
    ## from http://www.voidspace.org.uk/python/configobj.html
    ## confi/ini file that preserves comments
    # but not if you merge to a default dict... report bug?
    
    if ini_filename is None:
        ini_filename = get_ini_path()
    ini_filename = os.path.abspath(ini_filename)
    #default_data_path = this_module_path
    default_data_path = os.path.dirname(ini_filename)
        
    # code to load from file and use defaults if they are missing
    # BUT saves keeps/retains comments from file
    # merge is comment destructive so don't use it, even though it saves doing this below
    # NOTE this assign defaults only works for this project as there
    # are no sections in the ini file (ConfigObj can be tree-like)
    
    # move this out of this module and make caller pass in defaults
    # or at least out of this function
    import locale
    language_name, encoding_name = locale.getdefaultlocale()
    default_encoding = 'cp1252' ## default encoding used by Tombo (Windows and WindowsCE/PocketPC)
    default_encoding = sys.getdefaultencoding()
    if encoding_name != default_encoding:
        default_encoding = encoding_name ## Paranoid check, could just use it straight away
    DEFAULT_OPTIONS = ConfigObj({
            'filesystem_encoding': sys.getfilesystemencoding(),
            'file_encoding': default_encoding,  # encoding of the notes
            'windows_newlines': True, ## True/False - Save files with Windows Newlines ('\x0D\x0A') - needed for compatibility Tombo, loading our created notes in Tombo on dekstop and PocketPC
            'password_timeout': 300, ## 300 secs == 5 mins - how long after using password before "forgetting" or wiping password from memory so that password is asked for again
            'noteload_timeout': 200, ## 200 millisecs - delay between keypress in notetree and loading note text
            'backup_file_extension': '.bak',
            'split_direction': 'vertical', # or horizontal
            'date1_format': "%Y/%m/%d ",
            'date2_format': "%H:%M:%S",
            'spell_lang': "en_US", # what ever is valid for PyEnchant, in turn Enchant, could use locale.getdefaultlocale()[0]
            'debug': 'off', # "off" (default) or "on"
            'external_tool1':'"c:\\Program Files\\Scintilla Text Editor\\SciTE.exe" "%s"',
            'notedirectory': os.path.join(default_data_path, 'testnotes'), ## '../wxTombo20060904/testnotes' # make none or this module+testnotes
            'indexdirectory': os.path.join(default_data_path, '.testnotes_index') ## location of full text index (for Lupy this is a directory)
        })
    options = ConfigObj(ini_filename)
    for option_key in DEFAULT_OPTIONS:
        if not options.has_key(option_key):
            options[option_key] = DEFAULT_OPTIONS[option_key]

    # just in case integer coercion
    numeric_options_list = ['password_timeout', 'noteload_timeout']
    for option_key in numeric_options_list:
        options[option_key] = int(options[option_key])
    """
    if options['debug'] == 'on':
        ch.setLevel(logging.DEBUG)
    """
    #options.write()  ## gen default - debug only!!
    return options

    

def main():
    print get_ini_path()
    print get_ini_path('pants.ini')
    print get_ini_path(ini_filename='pants.ini')
    print get_ini_path('pants.ini', dirs_to_search=['/', '/tmp'])
    print get_ini_path('pants.ini', dir_if_not_found='/pants/sub/dir')
    print get_ini_path('pants.ini', ['/', '/tmp'], '/pants/sub/dir')
    print get_ini_path('pants.ini', dirs_to_search=['/', '/tmp'], dir_if_not_found='/pants/sub/dir')

if __name__ == '__main__':
    main()

